<template>
	<form class="px-[35px]" @submit.prevent="onEnter">
		<input type="submit" class="hidden" />
		<base-icon
			v-if="!accountStore.isLogin"
			name="back2"
			class="text-[20px] absolute left-3 top-3 cursor-pointer"
			@click="onBack" />
		<base-icon
			name="close"
			class="text-[20px] absolute right-3 top-3 cursor-pointer"
			@click="onClose" />
		<div class="h-12 mt-[50px] mb-4 pt-[12px] app-font-bold text-center text-[20px]">
			{{ $t('reset.title') }}
		</div>
		<base-tip class="mb-4" textT="reset.emailTitle"></base-tip>
		<base-input
			label-t="account.usernameOrEmailOrMobile"
			v-model="formValue.username"
			:name="[FormFieldName.username, FormFieldName.email, FormFieldName.mobile].join(',')"
			:autofocus="isPC()"
			:errorT="formRule.username.result.textT"
			:is-danger="!formRule.username.result.valid"
			:readonly="
				!!profileStore.userInfo?.email ||
				!!profileStore.userInfo?.mobile ||
				!!profileStore.userInfo?.username
			"
			@blur="formRule.username.validator()"
			@focus="formReset('username')">
			<template #prefix-out>
				<div v-if="phoneAreaShow" class="mr-2">
					<base-select
						v-model="formValue.mobileArea"
						:options="appStore.mobileAreaOptions"
						class="w-[103px]"
						filterable
						filter-field="text"
						:popoverProps="{ placement: 'bottom-start' }"
						icon-class="!h-5" />
				</div>
			</template>
		</base-input>
		<base-button type="primary" :loading="loading" @click="onEnter">
			{{ $t('action.confirm') }}
		</base-button>
		<app-captcha ref="captcha" type="login" />
	</form>
</template>

<script setup lang="ts">
import { computed, nextTick, reactive, ref, watch } from 'vue'
import { FormFieldName } from '@/enums'
import { fmtEmail, isEmail, isLength, isPC, isUsername, parseRegexp } from '@/utils'
import { BaseButton, BaseIcon, BaseInput, BaseSelect, BaseTip } from '@/components/base'
import { AppCaptcha } from '@/components/app/app-captcha'
import { useAccountStore, useAppStore, useDialogStore, useProfileStore } from '@/store'
import { AccountShowType, Action } from '@/types'
import { resetPasswordRequest } from '@/api/account'
import { useRequest } from '@/hooks'
import { RuleType } from '@/views/account/welcome/login.vue'
import { find } from 'lodash-es'

const captcha = ref(null)
const appStore = useAppStore()
const dialogStore = useDialogStore()
const accountStore = useAccountStore()
const profileStore = useProfileStore()
const onBack = () => accountStore.showAccount(AccountShowType.login)
const onClose = () => accountStore.showAccount(AccountShowType.none)
const phoneAreaShow = ref(false)
const formValue = reactive({
	username:
		profileStore.userInfo?.email ||
		profileStore.userInfo?.mobile ||
		profileStore.userInfo?.username ||
		'',
	mobileArea: !profileStore.userInfo?.email
		? profileStore.userInfo?.mobile
			? profileStore.userInfo?.internationalAreaCode || ''
			: ''
		: ''
})
const formRule = reactive({
	username: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.username.result = { valid: true })
			if (action === Action.input) formRule.username.hasInput = true
			if (action === Action.blur && !formRule.username.hasInput) return
			const value = formValue.username
			let msg: RuleType['textT'] = ''
			if (/^\d{3,}$/.test(value)) {
				// 电话号规则
				const item = find(appStore.mobileAreaOptions, { id: formValue.mobileArea })
				if (
					item &&
					!isLength(value, action === Action.input ? 0 : item.limitLength[0], item.limitLength[1])
				) {
					const regexp = parseRegexp(item.regexp)
					if (!regexp.test(value)) {
						msg = item.message
					}
				}
			} else if (value.includes('@')) {
				// 邮箱规则
				if (!isLength(value, 0, action === Action.input ? 128 : 0) && !isEmail(value)) {
					msg = 'register.emailRuleInvalid'
				}
			} else {
				// 用户名
				if (!value) {
					msg = 'register.usernameRuleRequired'
				} else if (!isUsername(value)) {
					msg = 'register.usernameRuleChar'
				} else if (!isLength(value, action === Action.input ? 0 : 3, 16)) {
					msg = 'register.usernameRuleLength'
				} else if (!/[a-zA-Z]/.test(value)) {
					msg = 'register.usernameRuleLetter'
				}
			}
			formRule.username.result = { textT: msg, valid: !msg }
		}
	}
})

const formReset = (field: keyof typeof formRule, withValue: boolean = false) => {
	if (withValue && formValue[field]) formValue[field] = ''
	nextTick(() => {
		formRule[field]?.hasInput && (formRule[field].hasInput = false)
		formRule[field]?.validator?.(Action.reset)
	})
}

watch([() => formValue.username, () => formValue.mobileArea], ([value]) => {
	phoneAreaShow.value = /^\d{3,}$/.test(value)
})

const { loading, run } = useRequest(resetPasswordRequest, {
	showError: true,
	onSuccess: (data: any) => {
		if (data?.email) {
			dialogStore.show('success', {
				icon: 'email',
				iconColor: 'var(--color-text-3)',
				titleT: 'reset.successSendTitle',
				contentT: ['reset.successSendContent', [fmtEmail(data?.email)]],
				confirmShow: true,
				confirmTextT: 'action.ok',
				cancelShow: false,
				closeFn: () => accountStore.showAccount(AccountShowType.none)
			})
		} else if (data.mobile) {
			accountStore.setResetResult(data)
			accountStore.showAccount(AccountShowType.forgotPasswordNext)
		}
	}
})

const submitDisabled = computed(
	() => !formValue.username || Object.values(formRule).some(({ result: { valid } }) => !valid)
)

const onSubmit = async () => {
	const resetPasswordUrl = location.origin + '/reset-password'
	const captchaObj = await (captcha.value as any).getValidate()
	await run({
		username: formValue.username.trim(),
		internationalAreaCode: formValue.mobileArea.trim() || null,
		resetPasswordUrl,
		...captchaObj
	})
}

const onEnter = () => {
	if (loading.value) return
	Object.values(formRule).forEach(({ validator }) => validator(Action.submit))
	nextTick(() => {
		if (submitDisabled.value) return
		onSubmit()
	})
}
</script>
